package com.ruoyi.common.utils.jm.ofd;

import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
import org.bouncycastle.crypto.params.*;
import org.bouncycastle.crypto.util.PrivateKeyInfoFactory;
import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.encoders.Base64Encoder;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;



public class SM2UtilForAgreement {

    public static AsymmetricCipherKeyPair ConvertToBCKeyPair(String sPublicKey,String sPrivateKey) throws IOException
    {
		ByteArrayOutputStream bOutput1 = new ByteArrayOutputStream();
		Base64Encoder b64 = new Base64Encoder();
		b64.decode(sPrivateKey,bOutput1);
		byte[] privateKey = bOutput1.toByteArray();
		bOutput1.reset();

		b64.decode(sPublicKey, bOutput1);
		byte[] publicKey = bOutput1.toByteArray();
		bOutput1.close();
        X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
        ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(),
                sm2ECParameters.getG(),
                sm2ECParameters.getN());
        ECPoint pukPoint = sm2ECParameters.getCurve().decodePoint(publicKey);
        ECPublicKeyParameters publicKeyParameters = new ECPublicKeyParameters(pukPoint, domainParameters);
        BigInteger privateKeyD = new BigInteger(1,privateKey);
        ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(privateKeyD, domainParameters);
        AsymmetricCipherKeyPair ak = new AsymmetricCipherKeyPair(publicKeyParameters,privateKeyParameters);
        return ak;
    }

    private static AsymmetricCipherKeyPair genKeyPair0() {
        //获取一条SM2曲线参数
        X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");

        //构造domain参数
        ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(),
                sm2ECParameters.getG(), sm2ECParameters.getN());

        //1.创建密钥生成器
        ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();

        //2.初始化生成器,带上随机数
        try {
            keyPairGenerator.init(new ECKeyGenerationParameters(domainParameters, SecureRandom.getInstance("SHA1PRNG")));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        //3.生成密钥对
        AsymmetricCipherKeyPair asymmetricCipherKeyPair = keyPairGenerator.generateKeyPair();

        return asymmetricCipherKeyPair;
    }

    public static PCIKeyPair genKeyPair() {
        return genKeyPair(true);
    }

    private static PCIKeyPair genKeyPair(boolean compressedPubKey) {
        AsymmetricCipherKeyPair asymmetricCipherKeyPair = genKeyPair0();
        //提取公钥点
        ECPoint ecPoint = ((ECPublicKeyParameters) asymmetricCipherKeyPair.getPublic()).getQ();
        //公钥前面的02或者03表示是压缩公钥,04表示未压缩公钥,04的时候,可以去掉前面的04
        byte[] pubKey = ecPoint.getEncoded(compressedPubKey);
        BigInteger privatekey = ((ECPrivateKeyParameters) asymmetricCipherKeyPair.getPrivate()).getD();
        byte[] priKey = privatekey.toByteArray();
        if(priKey[0] == 0)
        {
        	byte[] tmp = new byte[priKey.length - 1];
        	System.arraycopy(priKey, 1, tmp, 0, tmp.length);
        	priKey = tmp;
        }
        PCIKeyPair keyPair = new PCIKeyPair();
        keyPair.SetKeyPair(priKey, pubKey);
        return keyPair;
    }
}
